#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <UIKit/UIApplication.h>
#import <SpringBoard/SBApplicationController.h>
#import <SpringBoard/SBApplication.h>
#import <LockInfo/Plugin.h>

#import "framework/FWCommon.h"
#import "framework/FWPlugin.h"
#import "framework/FWApplication.h"

#import "PICommon.h"
#import "PIPlugin.h"
#import "PIIntegration.h"


@implementation PIPlugin

@synthesize appURLScheme, appDisplayIdentifier, appBundleIdentifier, foundPocketInformant;


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management

- (id)initWithApplication:(FWApplication*)app name:(NSString *)name
{
    if ((self = [super initWithApplication:app name:name])) {
        app.applicationDelegate = self;
        
        //NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
        //[center addObserver:self selector:@selector(update:) name:UIPasteboardChangedNotification object:nil];
    }        
    
    return self;
}

- (void)dealloc
{
    [appBundleIdentifier release];
    [appURLScheme release];
    [appDisplayIdentifier release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Checking database versions 

- (NSObject*)objectForSQLRecord:(sqlite3_stmt*)sqlStatement withId:(NSInteger)sqlid context:(NSObject*)context application:(FWApplication*)application
{
    int version = sqlite3_column_int(sqlStatement, 0);
    XLog(@"LI:PITodo: Detected PI database version %i", version);
    return @"OK";
}

- (BOOL)testDB:(FWApplication*)application path:(NSString*)path
{
    // Check the database appears to work
    NSString* test = @"select schemaversion from version";
    NSArray* value = FWDBGetRecords(test, 1, nil, path, application, self);
    return (value != nil);
}    


// ******************************************************************************************
#pragma mark -
#pragma mark Configuration and data management

static NSString* const kPublicAppRoot = @"/var/mobile";
static NSString* const kPIDBPath = @"/Documents/pidata.sqlite";
static NSString* const kPIPrefsPattern = @"/Library/Preferences/%@.plist";

- (BOOL)updateApplication:(FWApplication*)application
{
    SBApplication* app = [PIPlugin findPocketInformantForApplication:application];

    if (!app) {
        XLog(@"LI:PITodo: No application found");
        foundPocketInformant = NO;

#ifdef DEVELOPMENT_MODE
        foundPocketInformant = YES;
#endif
        
        return NO;
    }
    
    self.appURLScheme = app.urlScheme;
    self.appDisplayIdentifier = app.displayIdentifier;
    self.appBundleIdentifier = app.bundleIdentifier;

    // Check the database appears to work
    if (![self testDB:application path:application.databasePath]) {
        XLog(@"LI:PITodo: Database not readable at %@", application.databasePath);
                
        NSString* dbPath = [kPublicAppRoot stringByAppendingString:kPIDBPath];
        NSString* prefsPath = [kPublicAppRoot stringByAppendingFormat:kPIPrefsPattern, app.displayIdentifier];

        if ([self testDB:application path:dbPath]) {
            XLog(@"LI:PITodo: Database unexpectedly found at %@", dbPath);
            application.databasePath = dbPath;
            application.preferencesPath = prefsPath;
            foundPocketInformant = YES;
        }
    }
    else
        foundPocketInformant = YES;

    // Get initial config
    NSDictionary* prefs = [NSDictionary dictionaryWithContentsOfFile:application.preferencesPath];
    DebugLog(@"LI:PITodo: PI Preferences on startup = %@", prefs);
    
    XLog(@"LI:PITodo: Plugin bundle: %@", application.pluginBundle);
    XLog(@"LI:PITodo: App Path: %@", application.applicationPath);
    XLog(@"LI:PITodo: Prefs Path: %@", application.preferencesPath);
    XLog(@"LI:PITodo: DB Path: %@", application.databasePath);
    
    return YES;
}

+ (SBApplication*)findPocketInformantForApplication:(FWApplication*)application
{
    Class cls = objc_getClass("SBApplicationController");
    SBApplicationController* ctr = [cls sharedInstance];
    XLog(@"LI:PITodo: Got SB instance %@", ctr);
    
    XLog(@"LI:PIPlugin: Searching for application: %@", PIiPhoneIdentifier);
    SBApplication* app = [ctr applicationWithDisplayIdentifier:PIiPhoneIdentifier];
    if (app == nil) {
        XLog(@"LI:PITodo: Searching for application: %@", PIiPadIdentifier);
        app = [ctr applicationWithDisplayIdentifier:PIiPadIdentifier];
    }
    
    if (!app) {
        XLog(@"LI:PIPlugin: Couldn't find application");
        return nil;
    }

    XLog(@"LI:PIPlugin: Discovered application: %@", app);
    
    NSString* path = [app.path stringByDeletingLastPathComponent];
    application.applicationPath = app.path;
    application.preferencesPath = [path stringByAppendingFormat:kPIPrefsPattern, app.displayIdentifier];
    application.databasePath = [path stringByAppendingString:kPIDBPath];
    
    application.pluginBundle = application.fwPlugin.liPlugin.bundle;
    NSString* baseName = [[[application.pluginBundle bundlePath] lastPathComponent]
                          stringByReplacingOccurrencesOfString:@".bundle" withString:@".plist"];
    application.pluginPreferencesPath = [kPublicAppRoot stringByAppendingFormat:@"/Library/Preferences/%@", baseName];
    
    XLog(@"LI:PIPlugin: Application path = %@", application.applicationPath);
    XLog(@"LI:PIPlugin: Application preferences path = %@", application.preferencesPath);
    XLog(@"LI:PIPlugin: Application database path = %@", application.databasePath);
    XLog(@"LI:PIPlugin: Application plugin preferences path = %@", application.pluginPreferencesPath);
    
    XLog(@"LI:PIPlugin: Plugin bundle: %@", application.pluginBundle);
    
    UIPasteboard* pasteBoard = [UIPasteboard pasteboardWithName:kPIStatusPasteboard create:YES];
	pasteBoard.persistent = YES;

    pasteBoard.items = [NSArray arrayWithObjects:
                        [NSDictionary dictionaryWithObject:application.databasePath forKey:kPIPasteboardDBPath],
                        [NSDictionary dictionaryWithObject:application.applicationPath forKey:kPIPasteboardAppPath],
                        nil];
    
    return app;
}

- (BOOL)application:(FWApplication*)application shouldUpdateForDate:(NSDate*)date
{
    return NO;
}

@end
